/*
 * $Id: DataProvider.cs.cst,v 1.8 2005/11/22 15:46:06 莫光健(gdlmo) $
 * Last modified by $Author: 莫光健(gdlmo) $
 * Last modified at $Date: 2005/11/22 15:46:06 $
 * $Revision: 1.8 $

	Written By:
		莫光健(gdlmo)
	Description:
		这个脚本用于通用的设置及函数。
*/
using CodeSmith.Engine;
using SchemaExplorer;
using System;
using System.Windows.Forms.Design;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Diagnostics;

namespace gdlmo.Templates
{
	public class CommonScript : CodeTemplate
	{
		private TableSchema _DataSource 		= null;
		private string _CompanyName 			= "gygac";		//string.Empty;
		private string _ModuleName 				= "Dept";			//string.Empty;
		private string _CompanyURL 				= string.Empty;
		private string _Version 				= "01.00.00";	
		private string _outputDirectory  		="d:\\web\\dotnetnuke\\DesktopModules\\";
		
		
		// Hard coded Guid make it easier to maintain solution when regenerating projects
		// It may be intersting to put those value in global properties
		//public string slnGuid = "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC";		//
		//public string MainProjectGuid 		= "20E43088-4618-4F4A-B8AD-FC31B50D94CD"; //Guid.NewGuid().ToString();
		//public string SqlDataProjectGuid 	= "041C1BBE-0BFB-4D45-8125-9AB0BBC09A92"; //Guid.NewGuid().ToString();
		
		public string slnGuid = System.Guid.NewGuid().ToString();
		public string MainProjectGuid 		= System.Guid.NewGuid().ToString();
		public string SqlDataProjectGuid 	= System.Guid.NewGuid().ToString();
		
		#region "Common Property"		
		[Category("DataSource")]			//数据源（DataSource)
		[Description("产生对象所需依赖的表")]
		public TableSchema SourceTable
		{
			get {return this._DataSource;}
			set	{this._DataSource = value;}
		}
		[Category("General")]			//一般设置(General)
		[DefaultValue("gygac")]	
		[Description("公司名称")]
		public string CompanyName
		{
			get {return this._CompanyName;}
			set	{this._CompanyName = value;}
		}
		[Category("General")]			//一般设置(General)
		[Description("模块名称")]
		public string ModuleName
		{
			get {return this._ModuleName;}
			set	{this._ModuleName = value;}
		}
		[Category("General")]			//一般设置(General)
		[Description("公司网址")]
		public string CompanyURL
		{
			get {return this._CompanyURL;}
			set	{this._CompanyURL = value;}
		}
		[Category("General")]			//一般设置(General)
		[DefaultValue("01.00.00")]
		[Description("版本")]		
		public string Version
		{
			get {return this._Version;}
			set	{this._Version = value;}
		}
		[Category("General")]			//一般设置(General)
		[DefaultValue("")]
		[Description("输出目录")]		
		public string OutputDirectory 
		{ 
			get
			{		
				//if (_outputDirectory.Length == 0)
				//{				
					//return @"d:\web\dotnetnuke\DesktopModules\" + (SourceTable != null ? SourceTable.Name : "Output");
				//	return @"d:\web\dotnetnuke\DesktopModules\";
				//}
				//else
				//{
				return _outputDirectory;
				//}
			}
			set
			{
				if (value.EndsWith("\\")) value = value.Substring(0, value.Length - 1);
				_outputDirectory = value;
			} 
		}
		#endregion
		
		#region "Global Function"
		//得到Camel命名方式的字符串
		//调用示例：value = "Gygac_Dept"	输出：gygac_dept
		public string GetCamelCaseName(string value)
		{
			return value.Substring(0, 1).ToLower() + value.Substring(1);
		}
		
		//取得数据列的名称
		//调用示例：设有表gygac_Dept，其中有数据列 DeptId ,调用后输出 _DeptId
		public string GetMemberVariableName(ColumnSchema column)
		{
			string propertyName = GetPropertyName(column);			
			string memberVariableName = "_" + propertyName;
			return memberVariableName;
		}
		
		//取得属性名称
		//调用示例:
		public string GetPropertyName(ColumnSchema column)
		{
			string propertyName = column.Name;
			
			if (propertyName == column.Table.Name + "Name") return "Name";
			if (propertyName == column.Table.Name + "Description") return "Description";
			
			if (propertyName.EndsWith("TypeCode")) propertyName = propertyName.Substring(0, propertyName.Length - 4);
			
			return propertyName;
		}
		
		//取得表名,如表名中含有公司名称则去掉公司名称
		//调用示例: 设有表gygac_Dept ,其中gygac为公司名称，调用输出：Dept
		public string GetTableName(TableSchema table)			
		{
			//Debugger.Break();
			string strTemp = CompanyName;
			if( strTemp.Length > 0 )
			{
				if(table.Name.IndexOf(strTemp + "_")>-1)
				{
					strTemp += "_";	
				}
				
				return table.Name.Replace(strTemp, "");
			}
			else
			{
				return table.Name;
			}
		}	
		
		//取得原表名,如表名中含有dbo.字串则去掉
		//调用示例: 设有表dbo.dbogygac_Dept ,调用输出：gygac_Dept
		public string GetSourceTableName(TableSchema table)			
		{			
			string strTemp = "dbo.";
			
			if( table.Name.Length > 0 )
			{				
				return table.Name.Replace(strTemp, "");
			}
			else
			{
				return "";
			}
		}	
		
		//取Controller类类名
		//调用示例：设表名为 gygac_Dept ，调用后输出 DeptController
		public string GetCtlClassName(TableSchema table)
		{			
			return GetTableName(table) + "Controller";
		}
		
		//取Controller类类名
		//public string GetClassName(TableSchema table)
		//{
		//	string strTemp = CompanyName;
		//	if( strTemp.Length > 0 )
		//	{
		//		if(table.Name.IndexOf(strTemp + "_")>-1)
		//		{
		//			strTemp += "_";	
		//		}
				
		//		return (table.Name + "Controller").Replace(strTemp, "");
		//	}
		//	else
		//	{
		//		return (table.Name + "Controller");
		//	}			
		//}
		
		
		//取Info类类名
		//调用示例：设表名为 gygac_Dept ,调用后输出 DeptInfo
		public string GetInfoClassName(TableSchema table)
		{				
			return GetTableName(table) + "Info";
		}
		
		//取Controller类类名
		//调用示例：设表名为 gygac_Dept ,调用后输出 DeptController
		public string GetControllerClassName(TableSchema table)
		{				
			return GetTableName(table) + "Controller";
		}
		//取Info类类名
		/*
		public string GetClassNameInfo(TableSchema table)
		{	
			string strTemp = CompanyName;
			if( strTemp.Length > 0 )
			{
				if(table.Name.IndexOf(strTemp + "_")>-1)
				{
					strTemp += "_";	
				}
				
				return (table.Name + "Info").Replace(strTemp, "");
			}
			else
			{
				return (table.Name + "Info");
			}
		}
		*/
			
		//取成员变量宣称的访问权限
		public string GetMemberVariableDeclarationStatement(ColumnSchema column)
		{
			return GetMemberVariableDeclarationStatement("protected", column);
		}
		
		//成员变量及变量类型
		public string GetMemberVariableDeclarationStatement(string protectionLevel, ColumnSchema column)
		{			
			string statement = GetCSharpVariableType(column) + " " + GetMemberVariableName(column) + ";";			
			return statement;
		}
		
		#endregion
		
		#region "数据库处理相关"
		public string GetReaderAssignmentStatement(ColumnSchema column, int index)
		{
			string statement = "if (!reader.IsDBNull(" + index.ToString() + ")) ";
			statement += GetMemberVariableName(column) + " = ";
			
			if (column.Name.EndsWith("TypeCode")) statement += "(" + column.Name + ")";
			
			statement += "reader." + GetReaderMethod(column) + "(" + index.ToString() + ");";
			
			return statement;
		}
		
		//成员变量缺省值
		public string GetMemberVariableDefaultValue(ColumnSchema column)
		{
			switch (column.DataType)
			{
				case DbType.Guid:
				{
					return "Guid.Empty";
				}
				case DbType.AnsiString:
				case DbType.AnsiStringFixedLength:
				case DbType.String:
				case DbType.StringFixedLength:
				{
					return "string.Empty";
				}
				default:
				{
					return "";
				}
			}
		}
		
		//转换成CSharp类型
		public string GetCSharpVariableType(ColumnSchema column)
		{
			if (column.Name.EndsWith("TypeCode")) return column.Name;
			
			switch (column.DataType)
			{
				case DbType.AnsiString: return "string";
				case DbType.AnsiStringFixedLength: return "string";
				case DbType.Binary: return "byte()";
				case DbType.Boolean: return "bool";
				case DbType.Byte: return "byte";
				case DbType.Currency: return "decimal";
				case DbType.Date: return "DateTime";
				case DbType.DateTime: return "DateTime";
				case DbType.Decimal: return "decimal";
				case DbType.Double: return "double";
				case DbType.Guid: return "Guid";
				case DbType.Int16: return "short";
				case DbType.Int32: return "int";
				case DbType.Int64: return "long";
				case DbType.Object: return "object";
				case DbType.SByte: return "sbyte";
				case DbType.Single: return "float";
				case DbType.String: return "string";
				case DbType.StringFixedLength: return "string";
				case DbType.Time: return "TimeSpan";
				case DbType.UInt16: return "ushort";
				case DbType.UInt32: return "uint";
				case DbType.UInt64: return "ulong";
				case DbType.VarNumeric: return "decimal";
				default:
				{
					return "__UNKNOWN__" + column.NativeType;
				}
			}
		}
		
		//转换成VB类型
		public string GetVBVariableType(ColumnSchema column)
		{
			if (column.Name.EndsWith("TypeCode")) return column.Name;
			
			switch (column.DataType)
			{
				case DbType.AnsiString: return "string";
				case DbType.AnsiStringFixedLength: return "string";
				case DbType.Binary: return "byte()";
				case DbType.Boolean: return "Boolean";
				case DbType.Byte: return "byte";
				case DbType.Currency: return "decimal";
				case DbType.Date: return "DateTime";
				case DbType.DateTime: return "DateTime";
				case DbType.Decimal: return "decimal";
				case DbType.Double: return "double";
				case DbType.Guid: return "Guid";
				case DbType.Int16: return "short";
				case DbType.Int32: return "Integer";
				case DbType.Int64: return "long";
				case DbType.Object: return "object";
				case DbType.SByte: return "sbyte";
				case DbType.Single: return "float";
				case DbType.String: return "String";
				case DbType.StringFixedLength: return "String";
				case DbType.Time: return "TimeSpan";
				case DbType.UInt16: return "ushort";
				case DbType.UInt32: return "uint";
				case DbType.UInt64: return "ulong";
				case DbType.VarNumeric: return "decimal";
				default:
				{
					return "__UNKNOWN__" + column.NativeType;
				}
			}
		}
		
		//
		public string GetReaderMethod(ColumnSchema column)
		{
			switch (column.DataType)
			{
				case DbType.Byte:
				{
					return "GetByte";
				}
				case DbType.Int16:
				{
					return "GetInt16";
				}
				case DbType.Int32:
				{
					return "GetInt32";
				}
				case DbType.Int64:
				{
					return "GetInt64";
				}
				case DbType.AnsiStringFixedLength:
				case DbType.AnsiString:
				case DbType.String:
				case DbType.StringFixedLength:
				{
					return "GetString";
				}
				case DbType.Boolean:
				{
					return "GetBoolean";
				}
				case DbType.Guid:
				{
					return "GetGuid";
				}
				case DbType.Currency:
				case DbType.Decimal:
				{
					return "GetDecimal";
				}
				case DbType.DateTime:
				case DbType.Date:
				{
					return "GetDateTime";
				}
				default:
				{
					return "__SQL__" + column.DataType;
				}
			}
		}
		
		//转换成SQL数据类型
		public string GetSqlDbType(ColumnSchema column)
		{
			switch (column.NativeType)
			{
				case "bigint": return "BigInt";
				case "binary": return "Binary";
				case "bit": return "Bit";
				case "char": return "Char";
				case "datetime": return "DateTime";
				case "decimal": return "Decimal";
				case "float": return "Float";
				case "image": return "Image";
				case "int": return "Int";
				case "money": return "Money";
				case "nchar": return "NChar";
				case "ntext": return "NText";
				case "numeric": return "Decimal";
				case "nvarchar": return "NVarChar";
				case "real": return "Real";
				case "smalldatetime": return "SmallDateTime";
				case "smallint": return "SmallInt";
				case "smallmoney": return "SmallMoney";
				case "sql_variant": return "Variant";
				case "sysname": return "NChar";
				case "text": return "Text";
				case "timestamp": return "Timestamp";
				case "tinyint": return "TinyInt";
				case "uniqueidentifier": return "UniqueIdentifier";
				case "varbinary": return "VarBinary";
				case "varchar": return "VarChar";
				default: return "__UNKNOWN__" + column.NativeType;
			}
		}
		
		//取得表的主键CSharp类型,不支持多主键表
		//调用示例：设有表 gygac_Dept中主键为 DeptId（自动增长的int 类型），输出：int 		
		public string GetPrimaryKeyType(TableSchema table)
		{
			if (table.PrimaryKey != null)
			{
				if (table.PrimaryKey.MemberColumns.Count == 1)
				{
					return GetCSharpVariableType(table.PrimaryKey.MemberColumns[0]);
				}
				else
				{
					throw new ApplicationException("This template will not work on primary keys with more than one member column.");
				}
			}
			else
			{
				throw new ApplicationException("This template will only work on tables with a primary key.");
			}
		}
		
		//取得表的主键名称，不支持多主键表
		//调用示例：设有表 gygac_Dept中主键为 DeptId（自动增长的int 类型），输出：DeptId
		public string GetPrimaryKeyName(TableSchema table)
		{
			if (table.PrimaryKey != null)
			{
				if (table.PrimaryKey.MemberColumns.Count == 1)
				{
					return table.PrimaryKey.MemberColumns[0].Name;
				}
				else
				{
					throw new ApplicationException("This template will not work on primary keys with more than one member column.");
				}
			}
			else
			{
				throw new ApplicationException("This template will only work on tables with a primary key.");
			}
		}
		
		//取得表的主键名称及类型，支持多主键表
		//调用示例：设有表 gygac_Dept中主键为 DeptId（自动增长的int 类型），输出：int DeptId
		public string GetPrimaryKeyParameters(TableSchema table, bool includeTypes)
		{
			string parameters = "";
			if (table.PrimaryKey != null)
			{				
				for( int i = 0; i < table.PrimaryKey.MemberColumns.Count; i++ )
				{
					if(parameters.Length == 0)
					{						
						parameters = parameters + table.PrimaryKey.MemberColumns[i].Name;//不转换主键大小写
						
						if( includeTypes )
						{
							parameters = GetCSharpVariableType(table.PrimaryKey.MemberColumns[i]) + " " + parameters + " ";												
						}
					}
					else
					{
						parameters = parameters + ", ";						
						parameters = parameters + table.PrimaryKey.MemberColumns[i].Name;//不转换主键大小写
						if( includeTypes )
						{
							parameters = GetCSharpVariableType(table.PrimaryKey.MemberColumns[i]) + " " + parameters + " ";							
						}
					}
				}
			}
			else
			{
				throw new ApplicationException("This template will only work on tables with a primary key.");
			}
			return parameters;
		}
		
		//取非主键的键名及类型
		//调用示例：设有表 gygac_Dept中主键为 DeptId（自动增长的int 类型），外键：int ModuleId, 其它字段varchar(50) Name
		//输出：int ModuleId, string Name
		public string GetNonPrimaryKeyParameters(TableSchema table, bool includeTypes)
		{
			string parameters = "";
			if (table.PrimaryKey != null)
			{
				for( int i = 0; i < table.NonPrimaryKeyColumns.Count; i++ )
				{
					if(parameters.Length == 0)
					{						
						if( includeTypes )
						{							
							parameters = GetCSharpVariableType(table.NonPrimaryKeyColumns[i]) + " " + table.NonPrimaryKeyColumns[i].Name + " ";
						}
						else
						{						
							parameters = parameters + table.NonPrimaryKeyColumns[i].Name;							//不用Camel命名法
						}
					}
					else
					{
						parameters = parameters + ", ";	
						if( includeTypes )
						{							
							parameters = parameters + GetCSharpVariableType(table.NonPrimaryKeyColumns[i]) + " " + table.NonPrimaryKeyColumns[i].Name + " ";
						}
						else
						{						
							parameters = parameters + table.NonPrimaryKeyColumns[i].Name;
						}
					}
				}
			}
			else
			{
				throw new ApplicationException("This template will only work on tables with a primary key.");
			}
			return parameters;
		}
		
		//取数据列中键名及类型
		//调用示例：设有表 gygac_Dept中键为 DeptId（自动增长的int 类型）
		//输出：int DeptId
		public string GetNonPrimaryKeyParameters(ColumnSchema column, bool includeTypes)
		{
			string parameters = "";
			if( includeTypes )
			{							
				parameters = GetCSharpVariableType(column) + " " + column.Name + " ";
			}
			else
			{						
				parameters = column.Name + " ";						//不用Camel命名法
			}			
			return parameters;
		}
		
		//取值对象类型形式输出的主键
		//输入参数table ：要取得主键的表
		public string GetPrimaryKeyParametersForObject(TableSchema table, string obj)
		{
			string parameters = "";
			if (table.PrimaryKey != null)
			{
				for( int i = 0; i < table.PrimaryKey.MemberColumns.Count; i++ )
				{
					if(parameters.Length == 0)
					{
						parameters = parameters + obj + "." + table.PrimaryKey.MemberColumns[i].Name;
					}
					else
					{
						parameters = parameters + ", ";
						parameters = parameters + obj + "." + table.PrimaryKey.MemberColumns[i].Name;
					}
				}
			}
			else
			{
				throw new ApplicationException("This template will only work on tables with a primary key.");
			}
			return parameters;
		}
		
		public string GetNonPrimaryKeyParametersForObject(TableSchema table, string obj)
		{
			string parameters = "";
		
			for( int i = 0; i < table.NonPrimaryKeyColumns.Count; i++ )
			{
				if(parameters.Length == 0)
				{
					parameters = parameters + obj + "." + table.NonPrimaryKeyColumns[i].Name;
				}
				else
				{
					parameters = parameters + ", ";
					parameters = parameters + obj + "." + table.NonPrimaryKeyColumns[i].Name;
				}
			}
			
			return parameters;
		}
		
		public string OutPutRegisert()
		{
			return "Register";
		}		
		
		#endregion
	}
}